﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DeepTalkRenderServiceLib
{
    /// <summary>
    /// Helper class to calculate the next update time for a bunch of talks.
    /// </summary>
    public static class NextUpdateTimeCalculator
    {
        /// <summary>
        /// Given the start and the end and the "now", determine now long before we do another update
        /// for this conference.
        /// </summary>
        /// <param name="confStart"></param>
        /// <param name="confEnd"></param>
        /// <param name="now"></param>
        /// <returns></returns>
        public static TimeSpan RawTimeToUpdate(DateTime confStart, DateTime confEnd, DateTime now)
        {
            ///
            /// Get the Timespan of how long before the conference we are
            /// 

            TimeSpan before = confStart - now;
            if (before.TotalDays > 0.0)
            {
                ///
                /// Long before wait until one week before
                /// 

                if (before.TotalDays > 7)
                {
                    return before - TimeSpan.FromDays(7.0);
                }

                ///
                /// Now, less than a week, but more than 4 hours, we do it once a day, otherwise start 4 hours before
                /// the conference.
                /// 

                if (before.TotalDays < 1.0)
                {
                    if (before.TotalHours < 4.0)
                    {
                        return TimeSpan.FromHours(4.0);
                    }
                    return before - TimeSpan.FromHours(4.0);
                }

                return TimeSpan.FromDays(1.0);
            }

            ///
            /// Ok, we need to do during. NOTE: we don't drop down here if we are before teh conference start date, only after!
            /// 

            TimeSpan after = now - confEnd;
            if (after.TotalDays < 0.0)
            {
                return TimeSpan.FromHours(4.0);
            }

            ///
            /// Finally, after the start.
            /// 

            if (after.TotalHours < 24)
            {
                return TimeSpan.FromHours(12.0);
            }

            if (after.TotalDays < 7)
            {
                return TimeSpan.FromDays(1.0);
            }

            if (after.TotalDays < 31)
            {
                return TimeSpan.FromDays(4.0);
            }

            if (after.TotalDays < 6 * 31)
            {
                return TimeSpan.FromDays(31);
            }

            ///
            /// Good bye... we'll never need to do you again!
            /// 

            return TimeSpan.FromDays(0.0);
        }

        /// <summary>
        /// Time to update - how long before we do the next update?
        /// </summary>
        /// <param name="confStart"></param>
        /// <param name="confEnd"></param>
        /// <param name="now"></param>
        /// <returns></returns>
        public static TimeSpan TimeToUpdate(int numberOfTalksUpdated, DateTime confStart, DateTime confEnd, DateTime now)
        {
            var rawTimeToUpdate = RawTimeToUpdate(confStart, confEnd, now);
            if (numberOfTalksUpdated > 0 && rawTimeToUpdate.TotalDays > 1.0)
            {
                return TimeSpan.FromDays(1.0);
            }
            return rawTimeToUpdate;
        }
    }
}
